package com.bdqn.petmalldemo.utils;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bdqn.petmalldemo.common.SystemConstants;
import com.bdqn.petmalldemo.entity.Order;
import com.bdqn.petmalldemo.entity.OrderDetail;
import com.bdqn.petmalldemo.entity.Pay;
import com.bdqn.petmalldemo.entity.Product;
import com.bdqn.petmalldemo.service.OrderDetailService;
import com.bdqn.petmalldemo.service.OrderService;
import com.bdqn.petmalldemo.service.PayService;
import com.bdqn.petmalldemo.service.ProductService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author:彭俊
 * @description:支付工具类
 * @date:2020-03-23 15:31
 */
@Component
@Slf4j
public class AliPayUtil {
    @Resource
    private OrderService orderService;
    @Resource
    private PayService payService;
    @Resource
    private ProductService productService;
    @Resource
    private OrderDetailService orderDetailService;

    private int count = 0;

    /**
     * 查询支付结果
     * @param order
     */
    @Async
    @Transactional(rollbackFor = Exception.class)
    public void checkPayResult(Order order) {

        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipaydev.com/gateway.do",
                "2016101800713592",
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCiAk+/tfbLbJAQV8Fd0TqrqCl3wThHH+1S3E3rgWBpVIRiBTbN2uP78JFkNGuHyWTStiZf53UZQHkmVWOf/gx6ogX/VxLwnaDfp/oZ9uf57X/8lmbTKWOQPT/ecdA7268pHPA1zJvIjNyXZE0jhz0hY3aI3FS+78rX0Yw+fPQpfotndg/wsTkgn6PoXCriloIkYCT8dRg7jqk7uBTZuXKYWFTijEVCkTglfQ7qQTc9zBPPwuoN+DEeQ4uiFZf8cykl9X4+2d58iBGeLfd/QEfchdRrnZEBha6Rky4edFGhkv9W/YvI17By1hnOBctqv61p0Gd45GFUdOnMmZDMrU7ZAgMBAAECggEAA8Cl9DzUwJV9KMO/mNq1zzAP9dQl54/XwWmU7HWMtCPfBR41zMLbMQS7eWS1cOm7Sh4p+WK1Faamp7qmmhgaVeTW2rk7mRMtnMCZTGyppuJXapRZQV7eDYM9rXtZZWmLPxqKfdSFbznECkWqe74wLkvNfRINbHbFbgZOh0wBo8xfGBbDOY9H6PlbmZ11btmqVCNclSdb0i5Xh0bfSdGoGEJlopba1TACbkvPmtRa3Gs28KFJOWGjZGwoyXOOETYpfmieEayVKxaaFyjNF0lP6h8xSWdkcRtpuMAq2kUGfn+4zuCE8Iq5uO5LRwg+xMp1nSgYi/TyKdTVSkQ7uOxbWQKBgQDgAwcBfOoBzLG19xjeXhQI+XYNefTXraJju48KpDrrGPTmHTL94ByE7DxVJyXIuhAq7S9MiQdtktF8wcNXQwnSdktCMtueIHDa1VM8psLSCXtfSJW+72sJFKuKifXWKKYhVvCxoCeogUsEePdPB3s38P4Pr7gpXiwQJc22E5MFhwKBgQC5JLYAkbYanZTKBquuR0aTK/p/TpGga9RfiTMQKd3+6TaXaolFWo5l7wJYLbJALQnuTs6qOT41iX9YeGEssfPYG5Pko//Lttv9fHo5UCiZVbiYyd9fTy1lCei3vlaNxBqEhLeMvdMQbwLI4ckJ34TP7einYFzEeqt8YAvwyfQgnwKBgBwtxU/WmsknKqOtNZ+jTfnjB4qicL5AxVCuY0v/ZLn2Jbhcq/Fro6rE3MIJbqNVZHtB4tVJ13ldIqUC6sOrVyz2XHkzVJULl6avdw0GHTO2paJSyyN9koVN6FZBDH+oFV3URerSLqrvuLQTU2jJlCJxWkQ24n+xrPFLEBl7VN85AoGAFOKoSV4mndAC9dtUyJ8vvfBrHKtfUCp51aEjioI+kb/7MY+KFrHFeIhCynG1Nvodsa1gMOGuO9nb7L3/sEwOxuUthNBfTbq+DFVbcFWzjsCVx16WfSjwZQJ+JyQonWtu1l4mWpEbWzI6rTCTPjLhx5b99MuxC1UPPUOUdUBC8t8CgYB8bxLy9MpLnR6ZHAbaZbb3rjf9TIJ/g+4B54pow7QaH7awx63B3y8m7W0i8g6rPLc+gIfgjYBDC3C2Dz+BGKp0SUf4HIW12dW6CbOydJ5CaNp3C3/uRvaVIFzx9nVlX18I9s5w9lKkSnia8tAuWyhLF28yHNKt5auLJdMVKlGaLg==",
                //"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzAWYToJEco4B+B29lvpg/n3ep/lp9uO7Dzs41PtbEWQrqVf4U6z0sdsoMjJ0tXetphPY506Re0tCW/kCCegcJH1LfykZ3JbMAaG8bL/dRh9LfP1Jf3bjmLl3TXoo8tbn4Bk2UH/1SiHjZ6hfbDoUgJ3xb+7BfawXp0qZH+IUcM2Yo5An035N1qTpItOrOc8G3k7fnWvJ/g6PVbOF2RXN8cAv0div+lRX97jh0zxpeeZU+v8Dv7Oi3cIq5+iMp8UxaO8cy1AdGzrr75odk9vQq5pveWVo93MFvZ+68oZf5LELGHjmReCsd6+aAkbXh+ztmrbRvE4chymvqWzWWWcIAwIDAQAB",
                "json",
                "UTF-8",
                "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAg0KcspaZsp5GcGJDrgBevErggoL4wZ7b/sJAl4IaxozZznDkWef6wbMeeiEVGci76git8a+cjUWJdvx0V7sD0E7KYFxVUsduSfq3aA33f+/j21U94Rl+WLoSotT8b75BM8mlO7f/tirVCFNjvA/6HRAf6sFC2mwi480idgpQfKR+/0x9N277xkDIQe+X1HMde3QI55IQzSB8YCwsbaAC+NXsNe2jgMMEVBstyThN7FbfJmyITl1OaWOmZjPtOZIwZ/DQ6EUY08HR0pztZx5V6Y7oeVtqxQmzzFDq+jeP907QxxbfzdbajP61oumWU9MxEP8oMa8fuINo1KauvlG9IwIDAQAB",
                //"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAg0KcspaZsp5GcGJDrgBevErggoL4wZ7b/sJAl4IaxozZznDkWef6wbMeeiEVGci76git8a+cjUWJdvx0V7sD0E7KYFxVUsduSfq3aA33f+/j21U94Rl+WLoSotT8b75BM8mlO7f/tirVCFNjvA/6HRAf6sFC2mwi480idgpQfKR+/0x9N277xkDIQe+X1HMde3QI55IQzSB8YCwsbaAC+NXsNe2jgMMEVBstyThN7FbfJmyITl1OaWOmZjPtOZIwZ/DQ6EUY08HR0pztZx5V6Y7oeVtqxQmzzFDq+jeP907QxxbfzdbajP61oumWU9MxEP8oMa8fuINo1KauvlG9IwIDAQAB",
                "RSA2"); //获得初始化的AlipayClient
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();//创建API对应的request类
        request.setBizContent("{" +
                "    \"out_trade_no\":\"" + order.getId() + "\"}"); //设置业务参数
        AlipayTradeQueryResponse response = null;
        try {
            response = alipayClient.execute(request);
            //当返回的数据不成功的时候,继续回调，再来一次
            if (!response.isSuccess()) {
                //在执行回调操作的时候需要注意跳出的条件
                if (count<10){
                    count++;
                    log.info("第:{}次尝试查询支会结果",count);
                    checkPayResult(order);
                }

            } else {
                Pay pay = this.initPay(response, order);
                log.info("支付状态:{}", response.getTradeStatus());
                //交易状态：WAIT_BUYER_PAY（交易创建，等待买家付款）
                // TRADE_CLOSED（未付款交易超时关闭，或支付完成后全额退款）
                // TRADE_SUCCESS（交易支付成功）
                // TRADE_FINISHED（交易结束，不可退款）
                switch (response.getTradeStatus()) {
                    case "WAIT_BUYER_PAY":
                        checkPayResult(order);
                        break;
                    case "TRADE_CLOSED":
                        //更新订单状态
                        orderService.updateById(order.setStatus(SystemConstants.ORDER_STATUS.CLOSED));
                        //插入支付记录
                        pay.setPlatformTradeStatus("TRADE_CLOSED");
                        payService.save(pay);
                        //增加商品销量
                        updateProductSellNum(order.getId());
                        break;
                    case "TRADE_SUCCESS":
                        orderService.updateById(order.setStatus(SystemConstants.ORDER_STATUS.PAID));
                        pay.setPlatformTradeStatus("TRADE_SUCCESS");
                        //增加商品销量
                        updateProductSellNum(order.getId());
                        payService.save(pay);
                        break;
                    case "TRADE_FINISHED":
                        orderService.updateById(order.setStatus(SystemConstants.ORDER_STATUS.END));
                        pay.setPlatformTradeStatus("TRADE_FINISHED");
                        //增加商品销量
                        updateProductSellNum(order.getId());
                        payService.save(pay);
                        break;
                    default:
                        checkPayResult(order);
                        break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.print(response.getBody());
    }

    /**
     * 初始化支付记录对象
     *
     * @param response
     * @param order
     * @return
     */
    private Pay initPay(AlipayTradeQueryResponse response, Order order) {
        log.info("支付查询响应结果:{}", JSONObject.toJSONString(response));
        //处理相应数据中的body
        JSONObject jsonObject = JSONObject.parseObject(response.getBody());
        Date sendPayDate = jsonObject.getJSONObject("alipay_trade_query_response")
                .getDate("send_pay_date");
        //初始化一个支付记录对象
        Pay pay = new Pay();
        pay.setOrderId(order.getId())
                .setOrderNo(order.getOrderNo())
                .setUserId(order.getUserId())
                .setUsername(order.getUsername())
                .setPlatformTradeAmount(order.getPayment())
                //当前支付记录状态
                .setPlatformTradeStatus(response.getTradeStatus())
                //当前支付
                .setPlatformTradeNo(response.getTradeNo())
                //第三方平台支付时间(使用Instant类型作为日期格式的中间变量)
                .setPlatformPaymentTime(LocalDateTime.ofInstant(sendPayDate.toInstant(), ZoneId.systemDefault()))
                //第三方平台订单号
                .setPlatformTradeNo(jsonObject.getJSONObject("alipay_trade_query_response")
                        .getString("trade_no"))
                .setPayNo(jsonObject.getJSONObject("alipay_trade_query_response")
                        .getString("trade_no"));
        return pay;
    }

    /**
     * 根据订单Id更新相应商品的数量
     * @param orderId
     */
    private void updateProductSellNum(String orderId){
        //1.先查询当前订单中有哪些商品及数量
        List<OrderDetail> orderDetailList = orderDetailService.list(new QueryWrapper<OrderDetail>().eq("order_id", orderId));
        //当前订单对应的商品集合
        List<Product> productList = productService.listByIds(orderDetailList.stream().map(OrderDetail::getProductId).collect(Collectors.toList()));
        //根据当前订单详情处理相应的商品销售数量
        orderDetailList.forEach(orderDetail -> {
            //更新订单详情的状态为已付款
            orderDetail.setSendStatus(1);
            productList.forEach(product -> {
                //将当前订单详情中的商品Id与当前商品Id进行比对
                if (product.getId().equals(orderDetail.getProductId())) {
                    product.setSellNum(product.getSellNum()+orderDetail.getQuantity());
                }
            });
        });
        //批量完成数据更新
        productService.updateBatchById(productList);
        //批量完成订单详情的更新
        orderDetailService.updateBatchById(orderDetailList);
    }

}
